package org.rockyang.dike.interceptor;


import org.rockyang.dike.core.SubjectManager;
import org.rockyang.dike.core.impl.AuthorizationManager;
import org.rockyang.dike.exception.AuthenticationException;
import org.rockyang.dike.exception.AuthorizationException;
import org.rockyang.dike.exception.InvalidUrlException;
import org.rockyang.dike.surpport.ShiroxConfigure;
import org.rockyang.dike.utils.AuthorizationUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 授权认证拦截器
 * @author yangjian
 */
public class AuthorizationInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
			Exception {

		SubjectManager manager = AuthorizationUtils.getAuthorizationManager();
		manager.bindSession(request.getSession());
		//如果在黑名单，就直接拦截
		ShiroxConfigure configure = manager.getShiroxConfigure();
		if (configure.isInBlackList(request.getRequestURI())) {
			throw new InvalidUrlException("Your request has been dragged into the blacklist.");
		}
		// 如果是登录页面，则直接放行
		if (request.getRequestURI().equals(configure.getLoginUrl())) {
			return true;
		}
		// 如果在白名单，也直接放行
		if (configure.isInWhiteList(request.getRequestURI())) {
			return true;
		}
		//判断是否登录
		if (!manager.isAuthorized()) {
			if (null != configure.getLoginUrl()) {
				//跳转到登录页面
				response.sendRedirect(configure.getLoginUrl());
				return false;
			} else {
				throw new AuthenticationException("Authentication Failure.");
			}
		}

		//没有添加权限注解的全部放行
		String annotation = AuthorizationManager.getPermissionAnnotation(handler);
		if (null == annotation) {
			return true;
		}

        //判断是否授权
		if (!manager.hasPermission(annotation)) {
			if (null != configure.getUnAuthorizedUrl()) {
				//跳转到未授权页面
				response.sendRedirect(configure.getUnAuthorizedUrl());
				return false;
			} else {
				throw new AuthorizationException("No Authorization For Operation.");
			}
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
		// do nothing here
	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
		// do nothing here
	}
}
